home *** CD-ROM | disk | FTP | other *** search
/ Pascal Super Library / Pascal Super Library (CW International)(1997).bin / DELPHI32 / SEARCH / RUBICON / RBMAIN.PAS < prev    next >
Pascal/Delphi Source File  |  1996-10-21  |  46KB  |  1,588 lines

  1. {*********************************************************}
  2. {*              RBMAIN.PAS 1.20             *}
  3. {*      Copyright (c) Tamarack Associates 1996.     *}
  4. {*           All rights reserved.          *}
  5. {*********************************************************}
  6.  
  7. {$I TARUBICN.INC}
  8. {$B-}     {* Boolean evaluation *}
  9. {$G+}     {* Generate 286 code  *}
  10. {$X+}     {* eXtended syntax    *}
  11.  
  12. unit rbMain;
  13.  
  14. interface
  15.  
  16. uses
  17.   {$IFDEF WIN32}
  18.   Windows,
  19.   PrevInst,
  20.   {$ELSE}
  21.   WinTypes, WinProcs,
  22.   {$ENDIF}
  23.   SysUtils, Messages, Classes, Graphics, Controls, Forms, Dialogs,
  24.   StdCtrls, TabNotBk, DB, DBTables, Menus, Gauges, ExtCtrls,
  25.   {$IFDEF WIN32}
  26.   ComCtrls,
  27.   {$ENDIF}
  28.   {$IFDEF HaveSysTools}
  29.   StUtils,
  30.   {$ELSE}
  31.   taTools,
  32.   {$ENDIF}
  33.   taRubicn, taLink,
  34.   rbDBGrid, rbLink, rbPhase, rbAbout;
  35.  
  36. type
  37.   TSearchProc = PROCEDURE(Find : STRING) OF OBJECT;
  38.   TPage = (pgIntroduction,pgTable,pgBuild,pgSearch);
  39.   TPages = SET OF TPage;
  40.  
  41.   TMainForm = class(TForm)
  42.     TabbedNotebook1: TTabbedNotebook;
  43.     KeyViolTable1: TTable;
  44.     KeyViolDataSource: TDataSource;
  45.     MatchTable1: TTable;
  46.     MatchDataSource: TDataSource;
  47.     SearchTable1: TTable;
  48.     SearchDataSource: TDataSource;
  49.     WordsTable1: TTable;
  50.     WordsDataSource: TDataSource;
  51.     MakeDictionary1: TMakeDictionary;
  52.     SearchDictionary1: TSearchDictionary;
  53.     SaveDialog1: TSaveDialog;
  54.     OpenDialog1: TOpenDialog;
  55.  
  56.     {* Intro Tab *}
  57.     RubiconLabel: TLabel;
  58.     EngineLabel: TLabel;
  59.     CopyrightLabel: TLabel;
  60.     PrevBtn: TButton;
  61.     NextBtn: TButton;
  62.     StatusPanel: TPanel;
  63.     MOMemo: TMemo;
  64.  
  65.     {* Table Tab *}
  66.     TableGroupBox: TGroupBox;
  67.      AliasLabel: TLabel;
  68.      AliasComboBox: TComboBox;
  69.      TableLabel: TLabel;
  70.      TableComboBox: TComboBox;
  71.      IndexLabel: TLabel;
  72.      IndexComboBox: TComboBox;
  73.  
  74.     FieldsGroupBox: TGroupBox;
  75.      AvailLabel: TLabel;
  76.      AvailFldListBox: TListBox;
  77.      SelectFldListBox: TListBox;
  78.      SelectLabel: TLabel;
  79.      MoveRightBtn: TButton;
  80.      MoveLeftBtn: TButton;
  81.      AddLinkBtn: TButton;
  82.      EditLinkBtn: TButton;
  83.  
  84.     {* Build Tab *}
  85.     StatsGroupBox: TGroupBox;
  86.      StatElapsedLabel: TLabel;
  87.      StatWordLabel: TLabel;
  88.      StatMemLabel: TLabel;
  89.      StatMaxMemLabel: TLabel;
  90.      StatTableLabel: TLabel;
  91.      StatBlobLabel: TLabel;
  92.      StatCompressLabel: TLabel;
  93.      BuildTimeLabel: TLabel;
  94.      WordCountLabel: TLabel;
  95.      MemUsedLabel: TLabel;
  96.      MaxMemLabel: TLabel;
  97.      DBSizeLabel: TLabel;
  98.      MBSizeLabel: TLabel;
  99.      CompressionLabel: TLabel;
  100.      BuildBtn: TButton;
  101.  
  102.     BuildOptionsRadioGroup: TRadioGroup;
  103.     BuildNotebook: TNotebook;
  104.     TablesGroupBox: TGroupBox;
  105.      WordsLabel: TLabel;
  106.      KeyViolLabel: TLabel;
  107.      WordsEdit: TEdit;
  108.      KeyViolEdit: TEdit;
  109.      FileCompressionCheckBox: TCheckBox;
  110.  
  111.     WordDelimGroupBox: TGroupBox;
  112.      DelimsEdit: TEdit;
  113.  
  114.     IndexModeGroupBox: TGroupBox;
  115.      IndexModeComboBox: TComboBox;
  116.      StrictCheckingCheckBox: TCheckBox;
  117.  
  118.     OtherGroupBox: TGroupBox;
  119.      MinWordLenLabel: TLabel;
  120.      RecordLimitLabel: TLabel;
  121.      MemoryLimitLabel: TLabel;
  122.      MinWordLenEdit: TEdit;
  123.      RecordLimitEdit: TEdit;
  124.      MemoryComboBox: TComboBox;
  125.      AltMemMgrCheckBox: TCheckBox;
  126.  
  127.     {* Search Tab *}
  128.     SearchForGroupBox: TGroupBox;
  129.      SearchComboBox: TComboBox;
  130.      SearchBtn: TButton;
  131.     SearchResultsGroupBox: TGroupBox;
  132.      WordsBtn: TButton;
  133.      RecordsBtn: TButton;
  134.      ElapsedTimeLabel: TLabel;
  135.  
  136.     SearchOptionsRadioGroup: TRadioGroup;
  137.     SearchNotebook: TNotebook;
  138.     SearchLogicRadioGroup: TRadioGroup;
  139.     SearchModeRadioGroup: TRadioGroup;
  140.      SearchModeMemo : TMemo;
  141.     RankModeRadioGroup: TRadioGroup;
  142.      RankModeMemo: TMemo;
  143.  
  144.     SubFieldsGroupBox: TGroupBox;
  145.      SubFieldsAddAllBtn: TButton;
  146.      SubFieldsRemoveBtn: TButton;
  147.      SubFieldListBox: TListBox;
  148.  
  149.     CachingGroupBox: TGroupBox;
  150.      CacheMemLimitLabel: TLabel;
  151.      CacheMemoryLimitEdit: TEdit;
  152.      CachingDiskReadsLabel: TLabel;
  153.      CachingCacheReadsLabel: TLabel;
  154.      CachingMemoryUsageLabel: TLabel;
  155.      CachingSourceReadsLabel: TLabel;
  156.      DiskReadsLabel: TLabel;
  157.      CacheReadsLabel: TLabel;
  158.      SourceReadsLabel: TLabel;
  159.      MemoryUsageLabel: TLabel;
  160.      ResetBtn: TButton;
  161.      FlushBtn: TButton;
  162.  
  163.     MatchedWordsGroupBox: TGroupBox;
  164.      MatchingWordsListBox: TListBox;
  165.      MatchingWordsMemo: TMemo;
  166.  
  167.     SearchOtherGroupBox: TGroupBox;
  168.      MatchTableLabel: TLabel;
  169.      MatchedEdit: TEdit;
  170.      MatchRecordLimitLabel: TLabel;
  171.      MatchRecordLimitEdit: TEdit;
  172.      AnyCharLabel: TLabel;
  173.      AnyCharEdit: TEdit;
  174.      OneCharLabel: TLabel;
  175.      OneCharEdit: TEdit;
  176.      NearWordLabel: TLabel;
  177.      NearWordEdit: TEdit;
  178.  
  179.     {* Menus *}
  180.     MainMenu1: TMainMenu;
  181.     File1: TMenuItem;
  182.      NewMenuItem: TMenuItem;
  183.      OpenMenuItem: TMenuItem;
  184.      SaveMenuItem: TMenuItem;
  185.      SaveAsMenuItem: TMenuItem;
  186.      ExitMenuItem: TMenuItem;
  187.     View1: TMenuItem;
  188.      SearchTableMenuItem: TMenuItem;
  189.      WordsTableMenuItem: TMenuItem;
  190.      MatchTableMenuItem: TMenuItem;
  191.      KeyViolTableMenuItem: TMenuItem;
  192.      BreakMenuItem: TMenuItem;
  193.      ShowAllFieldsMenuItem: TMenuItem;
  194.     Help1: TMenuItem;
  195.      About1: TMenuItem;
  196.      Contents1: TMenuItem;
  197.      ShowHintsMenuItem: TMenuItem;
  198.  
  199.     procedure FormCreate(Sender: TObject);
  200.     procedure FormDestroy(Sender: TObject);
  201.     procedure NextBtnClick(Sender: TObject);
  202.     procedure PrevBtnClick(Sender: TObject);
  203.     procedure TabbedNotebook1Click(Sender: TObject);
  204.     procedure TabbedNotebook1Change(Sender: TObject; NewTab: Integer;
  205.       var AllowChange: Boolean);
  206.     procedure IntegerEditExit(Sender: TObject);
  207.     procedure MakeDictionary1PhaseOne(Sender: TObject);
  208.     procedure MakeDictionary1PhaseTwo(Sender: TObject);
  209.     {* Table Tab *}
  210.     procedure AliasComboBoxChange(Sender: TObject);
  211.     procedure TableComboBoxChange(Sender: TObject);
  212.     procedure IndexComboBoxChange(Sender: TObject);
  213.     procedure MoveRightBtnClick(Sender: TObject);
  214.     procedure MoveLeftBtnClick(Sender: TObject);
  215.     procedure AddLinkBtnClick(Sender: TObject);
  216.     procedure EditLinkBtnClick(Sender: TObject);
  217.     procedure AvailFldListBoxClick(Sender: TObject);
  218.     {* Build Tab *}
  219.     procedure BuildBtnClick(Sender: TObject);
  220.     procedure IndexModeComboBoxChange(Sender: TObject);
  221.     procedure BuildOptionsRadioGroupClick(Sender: TObject);
  222.     procedure KeyViolEditExit(Sender: TObject);
  223.     procedure WordsEditExit(Sender: TObject);
  224.     procedure MatchedEditExit(Sender: TObject);
  225.     {* Search Tab *}
  226.     procedure AnyCharEditExit(Sender: TObject);
  227.     procedure SearchBtnClick(Sender: TObject);
  228.     procedure SubFieldsAddAllBtnClick(Sender: TObject);
  229.     procedure SubFieldsRemoveBtnClick(Sender: TObject);
  230.     procedure SubFieldListBoxDblClick(Sender: TObject);
  231.     procedure ResetBtnClick(Sender: TObject);
  232.     procedure FlushBtnClick(Sender: TObject);
  233.     procedure SearchModeRadioGroupClick(Sender: TObject);
  234.     procedure WordsBtnClick(Sender: TObject);
  235.     procedure RecordsBtnClick(Sender: TObject);
  236.     procedure SearchComboBoxChange(Sender: TObject);
  237.     procedure SearchOptionsRadioGroupClick(Sender: TObject);
  238.     {* Menus *}
  239.     procedure SearchTableMenuItemClick(Sender: TObject);
  240.     procedure WordsTableMenuItemClick(Sender: TObject);
  241.     procedure MatchTableMenuItemClick(Sender: TObject);
  242.     procedure NewMenuItemClick(Sender: TObject);
  243.     procedure SaveMenuItemClick(Sender: TObject);
  244.     procedure SaveAsMenuItemClick(Sender: TObject);
  245.     procedure OpenMenuItemClick(Sender: TObject);
  246.     procedure ExitMenuItemClick(Sender: TObject);
  247.     procedure ShowAllFieldsMenuItemClick(Sender: TObject);
  248.     procedure About1Click(Sender: TObject);
  249.     procedure ShowHintsMenuItemClick(Sender: TObject);
  250.     procedure Contents1Click(Sender: TObject);
  251.  
  252.     procedure WordsTable1AfterOpen(DataSet: TDataset);
  253.     procedure SearchTable1CalcFields(DataSet: TDataset);
  254.     procedure SearchTable1AfterOpen(DataSet: TDataset);
  255.     procedure SearchTable1BeforeClose(DataSet: TDataset);
  256.     procedure WordsTable1BeforeClose(DataSet: TDataset);
  257.     procedure MatchTable1AfterOpen(DataSet: TDataset);
  258.     procedure MatchTable1BeforeClose(DataSet: TDataset);
  259.     procedure KeyViolTable1AfterOpen(DataSet: TDataset);
  260.     procedure KeyViolTable1BeforeClose(DataSet: TDataset);
  261.     procedure KeyViolTableMenuItemClick(Sender: TObject);
  262.     procedure SearchDictionary1Search(Sender: TObject);
  263.   private
  264.     { Private declarations }
  265.     FEditLink : TLinkData;
  266.     FFileName : STRING;
  267.     FFileNo   : INTEGER;
  268.     FLinkList : TLinkList;
  269.     FLastUpd  : LONGINT;
  270.     StartTime : TDateTime;
  271.     FTableType: TTableType;
  272.     FContinue : BOOLEAN;
  273.     FPages    : TPages;
  274.     PROCEDURE SetDefaults1;
  275.     PROCEDURE SetDefaults2;
  276.     PROCEDURE SetPages(Value : TPages);
  277.     PROCEDURE StructureTable(Table : TTable);
  278.     PROCEDURE ViewGridForm(DataSource : TDataSource);
  279.     PROCEDURE UpdateCacheStats;
  280.     PROPERTY  Pages : TPages READ FPages WRITE SetPages;
  281.   public
  282.     { Public declarations }
  283.     PROCEDURE Search;
  284.   end;
  285.  
  286. var
  287.   MainForm: TMainForm;
  288.  
  289. implementation
  290. {.$DEFINE Debug}
  291. {$R *.DFM}
  292.  
  293. CONST      FileSignature = 'Rubicon for Delphi Demo';
  294.       FileVersion    = $00010010;
  295.       RefreshTics    = 500;
  296.       SearchBtnCaption : ARRAY[TSearchMode] OF STRING[10] = ('Search','Narrow','Widen');
  297.       SearchBtnHint : ARRAY[TSearchMode] OF STRING[25] =
  298.                ('Perform a global search',
  299.                 'Narrow the search',
  300.                 'Widen the search');
  301.  
  302. PROCEDURE  SetComboBoxIndex(CB : TComboBox ; S : STRING);
  303. BEGIN
  304.  WITH CB DO ItemIndex := Items.IndexOf(S)
  305. END;
  306.  
  307. FUNCTION FindForm(Caption : STRING) : TForm;
  308. VAR i : INTEGER;
  309. BEGIN
  310.  Result := NIL;
  311.  WITH Application DO
  312.   FOR i := 0 TO ComponentCount - 1 DO
  313.    IF (Components[i] IS TForm) AND
  314.       (TForm(Components[i]).Caption = Caption) THEN
  315.     BEGIN
  316.      Result := TForm(Components[i]);
  317.      EXIT
  318.     END
  319. END;
  320.  
  321. {* Table must be closed *}
  322.  
  323. PROCEDURE FixupTable(Table : TTable);
  324. VAR      Alias : STRING;
  325. BEGIN
  326.  WITH Table DO
  327.   BEGIN
  328.    Alias := JustAliasName(TableName);
  329.    IF Alias <> '' THEN
  330.     BEGIN
  331.      DatabaseName := Alias;
  332.      TableName := COPY(TableName,LENGTH(Alias) + 3,LENGTH(TableName) - LENGTH(Alias) - 2)
  333.     END
  334.   END
  335. END;
  336.  
  337. FUNCTION NameChanged(Table : TTable ; NewName : STRING) : BOOLEAN;
  338. VAR     Alias : STRING;
  339. BEGIN
  340.  Alias := JustAliasName(NewName);
  341.  IF Alias = '' THEN Result := CompareText(NewName,Table.TableName) <> 0
  342.  ELSE
  343.   BEGIN
  344.    NewName := COPY(NewName,LENGTH(Alias) + 3,LENGTH(NewName) - LENGTH(Alias) - 2);
  345.    Result  := (CompareText(Alias,Table.DatabaseName) <> 0) OR
  346.           (CompareText(NewName,Table.TableName) <> 0)
  347.   END
  348. END;
  349.  
  350. PROCEDURE UpdateElapsedTime(L : TLabel);
  351. VAR      ElapsedTime    : LONGINT;
  352.       FormatSeconds : STRING[20];
  353. BEGIN
  354.  ElapsedTime := GetTickCount - L.Tag;
  355.  IF ElapsedTime < 1000 THEN FormatSeconds := '%4.3f seconds'
  356.  ELSE
  357.   IF ElapsedTime < 10000 THEN FormatSeconds := '%4.2f seconds'
  358.   ELSE FormatSeconds := '%4.1f seconds';
  359.  L.Caption := Format(FormatSeconds,[ElapsedTime/1000])
  360. END;
  361.  
  362. {$IFDEF Debug}
  363. {* Used only for testing the OmitList feature *}
  364. PROCEDURE LoadOmits(D : TAbstractDictionary);
  365. VAR      T : TTable;
  366. BEGIN
  367.  T := TTable.Create(NIL);
  368.  TRY
  369.   T.TableName := ExtractFilePath(ParamStr(0)) + 'omits.db';
  370.   TRY
  371.    D.LoadOmitsFromTable(T,'Word')
  372.   EXCEPT
  373.   END
  374.  FINALLY
  375.   T.Free
  376.  END
  377. END;
  378. {$ENDIF}
  379.  
  380. procedure TMainForm.FormCreate(Sender: TObject);
  381. begin
  382.  {$IFDEF WIN32}
  383.  IF DoIExist(Caption) THEN Application.Terminate;
  384.  {$ENDIF}
  385.  FFileNo   := 1;
  386.  FLinkList := TLinkList.Create;
  387.  SetDefaults1;
  388.  SetDefaults2;
  389.  Application.ShowHint := TRUE;
  390.  Application.HelpFile := ExtractFilePath(ParamStr(0)) + 'demo.hlp';
  391.  {$IFNDEF AltMemMgr}
  392.  AltMemMgrCheckBox.Enabled := FALSE;
  393.  {$ENDIF}
  394.  {$IFDEF Debug};
  395.  LoadOmits(MakeDictionary1);
  396.  {$ENDIF}
  397. end;
  398.  
  399. PROCEDURE TMainForm.SetDefaults1;
  400. BEGIN
  401.  FFileName := 'LINK' + IntToStr(FFileNo) + '.RDM';
  402.  Pages := [pgIntroduction,pgTable];
  403.  TabbedNotebook1.PageIndex := ORD(pgIntroduction);
  404.  TabbedNotebook1Click(TabbedNotebook1);
  405.  
  406.  MemoryComboBox.ItemIndex := 2; {* 8 mega bytes *}
  407.  WITH AliasComboBox DO
  408.   BEGIN
  409.    Session.GetAliasNames(Items);
  410.    IF Items.Count > 0 THEN
  411.     BEGIN
  412.      ItemIndex := 0;
  413.      AliasComboBoxChange(NIL)
  414.     END
  415.   END;
  416.  
  417. END;
  418.  
  419. PROCEDURE TMainForm.SetDefaults2;
  420. BEGIN
  421.  SearchLogicRadioGroup.ItemIndex := 0;
  422.  SearchModeRadioGroup.ItemIndex := 0;
  423.  RankModeRadioGroup.ItemIndex := 0;
  424.  ResetBtnClick(ResetBtn);
  425.  WordsEdit.Text := 'words';
  426.  MatchedEdit.Text := 'matched';
  427.  KeyViolEdit.Text := 'keyviol';
  428.  StrictCheckingCheckBox.Checked := TRUE;
  429.  MakeDictionary1.WordDelims := '';
  430.  DelimsEdit.Text := DefaultWordDelims;
  431.  FileCompressionCheckBox.Checked := TRUE;
  432.  MinWordLenEdit.Text := '3';
  433.  RecordLimitEdit.Text := '';
  434.  AltMemMgrCheckBox.Checked := TRUE;
  435.  SearchComboBox.Text := '';
  436.  SearchComboBox.Items.Clear;
  437.  MatchingWordsListBox.Items.Clear;
  438.  CacheMemoryLimitEdit.Text := '100000';
  439.  MatchRecordLimitEdit.Text := '100';
  440.  NearWordEdit.Text := '8';
  441.  AnyCharEdit.Text := '*';
  442.  OneCharEdit.Text := '?';
  443.  BuildTimeLabel.Caption := '';
  444.  WordCountLabel.Caption := '';
  445.  MemUsedLabel.Caption := '';
  446.  MaxMemLabel.Caption := '';
  447.  DBSizeLabel.Caption := '';
  448.  MBSizeLabel.Caption := '';
  449.  CompressionLabel.Caption := '';
  450.  WordsBtn.Caption := 'Words';
  451.  RecordsBtn.Caption := 'Records';
  452.  ElapsedTimeLabel.Caption := '0.00 Seconds';
  453.  FLastUpd := 0;
  454. END;
  455.  
  456. procedure TMainForm.AliasComboBoxChange(Sender: TObject);
  457. begin
  458.  WITH TableComboBox DO
  459.   TRY
  460.    Session.GetTableNames(AliasComboBox.Items[AliasComboBox.ItemIndex],'',TRUE,FALSE,Items);
  461.    IF Items.Count > 0 THEN
  462.     BEGIN
  463.      ItemIndex := 0;
  464.      TableComboBoxChange(NIL)
  465.     END
  466.    ELSE
  467.     BEGIN
  468.      AvailFldListBox.Items.Clear;
  469.      SelectFldListBox.Items.Clear;
  470.     END
  471.   EXCEPT
  472.    RAISE
  473.   END
  474. end;
  475.  
  476. procedure TMainForm.TableComboBoxChange(Sender: TObject);
  477. begin
  478.  WITH SearchTable1 DO
  479.   BEGIN
  480.    Close;
  481.    WordsTable1.Close;
  482.    KeyViolTable1.Close;
  483.    MatchTable1.Close;
  484.    FLinkList.ClearLinks;
  485.    SetDefaults2;
  486.    WITH AliasComboBox DO
  487.     DatabaseName := Items[ItemIndex];
  488.    WITH TableComboBox DO
  489.     TableName := Items[ItemIndex];
  490.    IndexName := '';
  491.    WordsTable1.DatabaseName := DatabaseName;
  492.    MatchTable1.DatabaseName := DatabaseName;
  493.    StructureTable(SearchTable1);
  494.    MakeDictionary1.DataSource := NIL;
  495.    Open;
  496.    FTableType := GetTableType(SearchTable1);
  497.    WordsTable1.TableType := FTableType;
  498.    MatchTable1.TableType := FTableType;
  499.    MakeDictionary1.IndexMode := SafeIndexMode(SearchTable1);
  500.    MakeDictionary1.DataSource := SearchDataSource;
  501.    IndexComboBox.Clear;
  502.    GetIndexNames(IndexComboBox.Items);
  503.    GetFieldNames(AvailFldListBox.Items);
  504.    MakeDictionary1.IndexMode := SafeIndexMode(SearchTable1);
  505.    IndexModeComboBox.ItemIndex := ORD(MakeDictionary1.IndexMode);
  506.    MakeDictionary1.DataSource := SearchDataSource; {* Force a reset of FResultBits *}
  507.    SelectFldListBox.Items.Clear;
  508.    SubFieldListBox.Clear;
  509.    Pages := Pages - [pgBuild];
  510.   END
  511. end;
  512.  
  513. procedure TMainForm.IndexComboBoxChange(Sender: TObject);
  514. begin
  515.  TRY
  516.   WITH IndexComboBox, SearchTable1 DO
  517.    IF ItemIndex >= 0 THEN
  518.     IndexName := Items[ItemIndex]
  519.    ELSE
  520.     IndexName := ''
  521.  EXCEPT
  522.   ON EDatabaseError DO
  523.  END
  524. end;
  525.  
  526. procedure TMainForm.NextBtnClick(Sender: TObject);
  527. begin
  528.  WITH TabbedNotebook1 DO PageIndex := PageIndex + 1;
  529.  TabbedNotebook1Click(TabbedNotebook1)
  530. end;
  531.  
  532. procedure TMainForm.PrevBtnClick(Sender: TObject);
  533. begin
  534.  WITH TabbedNotebook1 DO PageIndex := PageIndex - 1;
  535.  TabbedNotebook1Click(TabbedNotebook1)
  536. end;
  537.  
  538. procedure TMainForm.MoveRightBtnClick(Sender: TObject);
  539. VAR i : INTEGER;
  540. begin
  541.  WITH AvailFldListBox DO
  542.   IF SelCount > 0 THEN
  543.    FOR i := Items.Count - 1 DOWNTO 0 DO
  544.     IF Selected[i] THEN
  545.      BEGIN
  546.       SelectFldListBox.Items.Add(Items[i]);
  547.       IF NOT ShowAllFieldsMenuItem.Checked THEN
  548.        SearchTable1.FieldByName(Items[i]).Visible := TRUE;
  549.       Items.Delete(i)
  550.      END;
  551.  IF NOT (pgBuild IN Pages) THEN
  552.   IF SelectFldListBox.Items.Count > 0 THEN
  553.    BEGIN
  554.     Pages := Pages + [pgBuild];
  555.     ShowAllFieldsMenuItem.Enabled := TRUE
  556.    END
  557. end;
  558.  
  559. procedure TMainForm.MoveLeftBtnClick(Sender: TObject);
  560. VAR i : INTEGER;
  561. begin
  562.  WITH SelectFldListBox DO
  563.   IF SelCount > 0 THEN
  564.    FOR i := Items.Count - 1 DOWNTO 0 DO
  565.     IF Selected[i] THEN
  566.      BEGIN
  567.       AvailFldListBox.Items.Add(Items[i]);
  568.       IF NOT ShowAllFieldsMenuItem.Checked THEN
  569.        SearchTable1.FieldByName(Items[i]).Visible := FALSE;
  570.       Items.Delete(i)
  571.      END;
  572.   IF (pgBuild IN Pages) AND
  573.      (SelectFldListBox.Items.Count = 0) THEN
  574.    BEGIN
  575.     Pages := Pages - [pgBuild];
  576.     WITH ShowAllFieldsMenuItem DO
  577.      BEGIN
  578.       Enabled := FALSE;
  579.       IF NOT Checked THEN ShowAllFieldsMenuItemClick(ShowAllFieldsMenuItem)
  580.      END
  581.    END
  582. end;
  583.  
  584. procedure TMainForm.ViewGridForm(DataSource : TDataSource);
  585. VAR      F : TDBGridForm;
  586.       GridCaption : STRING;
  587. BEGIN
  588.  GridCaption := UpperCase(TTable(DataSource.DataSet).TableName);
  589.  F := TDBGridForm(FindForm(GridCaption));
  590.  IF F = NIL THEN
  591.   BEGIN
  592.    Application.CreateForm(TDBGridForm,F);
  593.    F.Grid.DataSource := DataSource;
  594.    F.Caption := GridCaption;
  595.    F.Show
  596.   END
  597.  ELSE
  598.   BEGIN
  599.    IF F.WindowState = wsMinimized THEN
  600.     F.WindowState := wsNormal;
  601.    F.BringToFront
  602.   END
  603. END;
  604.  
  605. procedure TMainForm.SearchTableMenuItemClick(Sender: TObject);
  606. begin
  607.  ViewGridForm(SearchDataSource)
  608. end;
  609.  
  610. procedure TMainForm.BuildBtnClick(Sender: TObject);
  611. CONST      MemoryA : ARRAY[0..4] OF INTEGER = (16,12,8,4,2);
  612. begin
  613.  {$IFNDEF WIN32}
  614.  HeapLimit := 16384;
  615.  HeapBlock := {HeapLimit * 8}65535;
  616.  {$ENDIF}
  617.  Screen.Cursor := crHourGlass;
  618.  WITH MakeDictionary1 DO
  619.   TRY
  620.    WordsTable1.Close;
  621.    WordsTable1.TableName := WordsEdit.Text;
  622.    FixupTable(WordsTable1);
  623.    KeyViolTable1.Close;
  624.    KeyViolTable1.TableName := AliasToPath(KeyViolEdit.Text);
  625.    FixupTable(MatchTable1);
  626.    MatchTable1.Close;
  627.    MatchTable1.TableName := MatchedEdit.Text;
  628.    FixupTable(MatchTable1);
  629.    FieldNames.Assign(SelectFldListBox.Items);
  630.    FileCompression := FileCompressionCheckBox.Checked;
  631.    MemoryLimit       := MemoryA[MemoryComboBox.ItemIndex] * 1048575 {2^20 - 1};
  632.    WordDelims       := DelimsEdit.Text;
  633.    MinWordLen       := StrToInt(MinWordLenEdit.Text);
  634.    StrictChecking  := StrictCheckingCheckBox.Checked;
  635.    IndexMode       := TIndexMode(IndexModeComboBox.ItemIndex);
  636.    KeyViolName       := KeyViolEdit.Text;
  637.    IndexFieldName  := 'AltIndex';
  638.    {$IFDEF AltMemMgr}
  639.    AltMemMgr       := AltMemMgrCheckBox.Checked;
  640.    {$ENDIF}
  641.    WITH RecordLimitEdit DO
  642.     IF Text = '' THEN RecordLimit := 0
  643.     ELSE RecordLimit := StrToInt(Text);
  644.    StartTime := Now;
  645.    Execute;
  646.    Pages := Pages + [pgSearch]
  647.   FINALLY
  648.    {$IFDEF Debug}
  649.    State := [];
  650.    MakeDictionary1PhaseTwo(MakeDictionary1);
  651.    {$ENDIF}
  652.    TRY
  653.     IF TableExists(KeyViolTable1) THEN
  654.      KeyViolTable1.Open
  655.    EXCEPT
  656.    END;
  657.    Screen.Cursor := crDefault;
  658.    PhaseForm.Hide
  659.   END;
  660. end;
  661.  
  662. procedure TMainForm.SearchBtnClick(Sender: TObject);
  663. begin
  664.  WITH Sender AS TButton DO
  665.   BEGIN
  666.    IF (Caption = SearchBtnCaption[SearchDictionary1.SearchMode]) AND
  667.       (SearchDictionary1.State = []) THEN
  668.     TRY
  669.      FContinue := TRUE;
  670.      Caption := 'Stop';
  671.      Search
  672.     FINALLY
  673.      Caption := SearchBtnCaption[SearchDictionary1.SearchMode]
  674.     END
  675.   ELSE FContinue := FALSE
  676.  END
  677. end;
  678.  
  679. procedure TMainForm.Search;
  680. BEGIN
  681.  {$IFDEF Debug}
  682.  WITH MakeDictionary1 DO
  683.   BEGIN
  684.    FieldNames.Assign(SelectFldListBox.Items);
  685.    WordDelims       := DelimsEdit.Text;
  686.    StrictChecking  := StrictCheckingCheckBox.Checked;
  687.    IndexMode       := TIndexMode(IndexModeComboBox.ItemIndex);
  688.    MinWordLen       := StrToInt(MinWordLenEdit.Text);
  689.   END;
  690.  {$ENDIF}
  691.  WITH SearchDictionary1 DO
  692.   BEGIN
  693.    AnyChar       := AnyCharEdit.Text[1];
  694.    NearWord       := StrToInt(NearWordEdit.Text);
  695.    OneChar       := OneCharEdit.Text[1];
  696.    RankMode       := TRankMode(RankModeRadioGroup.ItemIndex);
  697.    RecordLimit       := StrToInt(MatchRecordLimitEdit.Text);
  698.    SearchLogic       := TSearchLogic(SearchLogicRadioGroup.ItemIndex);
  699.    IF CacheMemoryLimitEdit.Text <> '' THEN
  700.     MemoryLimit    := StrToInt(CacheMemoryLimitEdit.Text)
  701.    ELSE
  702.     MemoryLimit    := 0;
  703.    IF (SubFieldListBox.Items.Count > 0) AND
  704.       (SubFieldListBox.Items.Count < SelectFldListBox.Items.Count) THEN
  705.     SubFieldNames := SubFieldListBox.Items
  706.    ELSE
  707.     SubFieldNames.Clear;
  708.    WITH SearchComboBox DO
  709.     BEGIN
  710.      Screen.Cursor := crHourGlass;
  711.      TRY
  712.       ElapsedTimeLabel.Tag := GetTickCount;
  713.       SearchFor  := Text;
  714.       Execute;
  715.      FINALLY
  716.       UpdateElapsedTime(ElapsedTimeLabel);
  717.       Screen.Cursor := crDefault;
  718.       IF (ItemIndex = -1) AND (Text <> '') THEN Items.Insert(0,Text);
  719.       IF ItemIndex > 0 THEN
  720.        BEGIN
  721.     Items.Insert(0,Items[ItemIndex]);  {* This will adjust ItemIndex up 1 *}
  722.     Items.Delete(ItemIndex);       {* Not ItemIndex + 1!          *}
  723.     ItemIndex := 0
  724.        END;
  725.      END
  726.     END;
  727.    RecordsBtn.Caption := 'Records ' + IntToStr(RecordCount);
  728.    WordsBtn.Caption := 'Words ' + IntToStr(MatchCount);
  729.    IF (FindForm(SysUtils.UpperCase(MatchTable1.TableName)) <> NIL) AND
  730.       (RecordCount <= RecordLimit) THEN
  731.     BEGIN
  732.      CreateMatchTable(MatchTable1);
  733.      StructureTable(MatchTable1)
  734.     END
  735.    ELSE MatchTable1.Tag := 1;
  736.    WordsBtn.Enabled :=    MatchCount > 0;
  737.    RecordsBtn.Enabled := RecordCount > 0;
  738.    MatchTableMenuItem.Enabled := RecordsBtn.Enabled;
  739.    MatchingWordsListBox.Items.Clear;
  740.    SearchDictionary1.MatchingWords(MatchingWordsListBox.Items)
  741.   END
  742. END;
  743.  
  744. procedure TMainForm.AddLinkBtnClick(Sender: TObject);
  745. VAR      Link : TLinkData;
  746.       List : TStrings;
  747.       i    : INTEGER;
  748.  
  749.  PROCEDURE DeleteLink;
  750.  BEGIN
  751.   IF FEditLink = NIL THEN EXIT;
  752.   WITH FLinkList DO
  753.    DeleteLink(IndexOf(FEditLink));        {* can invalidate other links *}
  754.   WITH TListBox(EditLinkBtn.Tag) DO Items.Delete(ItemIndex);
  755.   FEditLink := NIL;
  756.  END;
  757.  
  758. begin
  759.  Application.CreateForm(TLinkForm,LinkForm);
  760.  WITH LinkForm DO
  761.   TRY
  762.  { SearchTable1.GetFieldNames(DataFieldComboBox.Items); }
  763.    GetNonCalcFieldNames(SearchTable1,DataFieldComboBox.Items);
  764.    WITH AliasComboBox DO
  765.     Session.GetTableNames(Items[ItemIndex],'',TRUE,FALSE,LinkTableComboBox.Items);
  766.    LinkTable.DatabaseName := SearchTable1.DatabaseName;
  767.    EditLink := FEditLink;
  768.    CASE ShowModal OF
  769.     mrOk :
  770.      BEGIN
  771.       DeleteLink;
  772.       Link := TLinkData.Create;
  773.       WITH Link DO
  774.        BEGIN
  775.     DataField      := DataFieldComboBox.Text;
  776.     LinkDisplay    := LinkDisplayComboBox.Text;
  777.     LinkTableName  := LinkTableComboBox.Text;
  778.     LinkFieldNames := LinkFieldComboBox.Text;
  779.     LinkTable.DatabaseName := SearchTable1.DatabaseName;
  780.     List := TStringList.Create;
  781.     TRY
  782.      DisplayFieldsList(List);
  783.      FOR i := 0 TO List.Count - 1 DO
  784.       SelectFldListBox.Items.Add(JustFileName(LinkTableName) + List[I])
  785.     FINALLY
  786.      List.Free
  787.     END
  788.        END;
  789.       FLinkList.Add(Link);
  790.       Link.CreateLinkFields(SearchTable1)
  791.      END;
  792.     mrNo : DeleteLink;
  793.     ELSE FEditLink := NIL
  794.    END
  795.   FINALLY
  796.    Release
  797.   END;
  798.  IF NOT (pgBuild IN Pages) THEN
  799.   BEGIN
  800.    IF SelectFldListBox.Items.Count > 0 THEN Pages := Pages + [pgBuild];
  801.    ShowAllFieldsMenuItem.Enabled := pgBuild IN Pages
  802.   END
  803. end;
  804.  
  805. procedure TMainForm.EditLinkBtnClick(Sender: TObject);
  806. VAR      FieldName : STRING;
  807.       Index     : INTEGER;
  808. begin
  809.  WITH TListBox(EditLinkBtn.Tag) DO FieldName := Items[ItemIndex];
  810.  Index := FLinkList.FindLinkDisplayField(FieldName,TRUE);
  811.  IF Index >= 0 THEN FEditLink := FLinkList.Items[Index];
  812.  AddLinkBtnClick(Self);
  813.  IF FEditLink <> NIL THEN
  814.   BEGIN
  815.    WITH FLinkList DO DeleteLink(IndexOf(FEditLink));
  816.    FEditLink := NIL
  817.   END;
  818.  AvailFldListBoxClick(TObject(EditLinkBtn.Tag))
  819. end;
  820.  
  821. procedure TMainForm.AvailFldListBoxClick(Sender: TObject);
  822. VAR      Field   : TField;
  823.       CanEdit : BOOLEAN;
  824. begin
  825.  CanEdit := FALSE;
  826.  WITH Sender AS TListBox,SearchTable1 DO
  827.   IF SelCount = 1 THEN
  828.    BEGIN
  829.     Field := FindField(Items[ItemIndex]);
  830.     IF Field <> NIL THEN CanEdit := Field.Calculated
  831.    END;
  832.  EditLinkBtn.Enabled := CanEdit;
  833.  EditLinkBtn.Tag := LONGINT(Sender)
  834. end;
  835.  
  836. procedure TMainForm.SearchTable1CalcFields(DataSet: TDataset);
  837. VAR      i,j : INTEGER;
  838.       JustName,DisplayName : STRING;
  839.       Field : TField;
  840. begin
  841.  FOR i := 0 TO FLinkList.Count - 1 DO
  842.   WITH TLinkData(FLinkList.Items[i]),DataSet DO
  843.    BEGIN
  844.     IF NOT LinkTable.Active THEN LinkTable.Open;
  845.     IF LinkTable.FindKey([FieldByName(DataField).AsString]) THEN
  846.      BEGIN
  847.       JustName := JustFileName(LinkTable.TableName);
  848.       j := 1;
  849.       WHILE j < LENGTH(LinkDisplay) DO
  850.        BEGIN
  851.     DisplayName := ExtractFieldName(LinkDisplay,j);
  852.     Field := FindField(JustName + DisplayName);
  853.     IF Field <> NIL THEN
  854.      Field.AsString := LinkTable.FieldByname(DisplayName).AsString
  855.        END
  856.      END
  857.    END
  858. end;
  859.  
  860. procedure TMainForm.WordsTableMenuItemClick(Sender: TObject);
  861. begin
  862.  ViewGridForm(WordsDataSource)
  863. end;
  864.  
  865. procedure TMainForm.MatchTableMenuItemClick(Sender: TObject);
  866. begin
  867.  IF MatchTable1.Tag <> 0 THEN
  868.   BEGIN
  869.    MatchTable1.Tag := 0;
  870.    Screen.Cursor := crHourGlass;
  871.    TRY
  872.     SearchDictionary1.RankMode      := TRankMode(RankModeRadioGroup.ItemIndex);
  873.     SearchDictionary1.RecordLimit := StrToInt(MatchRecordLimitEdit.Text);
  874.     SearchDictionary1.CreateMatchTable(MatchTable1)
  875.    FINALLY
  876.     Screen.Cursor := crDefault
  877.    END
  878.   END;
  879.  StructureTable(MatchTable1);
  880.  ViewGridForm(MatchDataSource)
  881. end;
  882.  
  883. PROCEDURE TMainForm.StructureTable(Table : TTable);
  884. VAR      i     : INTEGER;
  885.       Field  : TField;
  886.       Reopen : BOOLEAN;
  887. BEGIN
  888.  WITH Table DO
  889.   BEGIN
  890.    Reopen := Active;
  891.    Close;
  892.    FreeFields(Table);
  893.    FieldDefs.Update;
  894.    FOR i := 0 TO FieldDefs.Count - 1 DO
  895.     FieldDefs[i].CreateField(Table);
  896.    FOR i := 0 TO FLinkList.Count - 1 DO
  897.     TLinkData(FLinkList[i]).CreateLinkFields(Table);
  898.    IF NOT ShowAllFieldsMenuItem.Checked THEN
  899.     FOR i := 0 TO AvailFldListBox.Items.Count - 1 DO
  900.      BEGIN
  901.       Field := FindField(AvailFldListBox.Items[i]);
  902.       IF Field <> NIL THEN Field.Visible := FALSE
  903.      END;
  904.    IF Reopen THEN Open
  905.   END
  906. END;
  907.  
  908. procedure TMainForm.SaveMenuItemClick(Sender: TObject);
  909. VAR      Stream : TFileStream;
  910.       Writer : TWriter;
  911.       i     : INTEGER;
  912.       List     : TStrings;
  913.       Save     : BOOLEAN;
  914. begin
  915.  List := TStringList.Create;
  916.  WITH SaveDialog1 DO
  917.   TRY
  918.    WITH AliasComboBox DO
  919.     Session.GetAliasParams(Items[ItemIndex],List);
  920.    SaveDialog1.InitialDir := List.Values['PATH'];
  921.    FileName := FFileName;
  922.    Save := Execute;
  923.    IF Save THEN FFileName := FileName
  924.   FINALLY
  925.    List.Free
  926.   END;
  927.  IF NOT Save THEN EXIT;
  928.  Stream := TFileStream.Create(FFileName,fmCreate);
  929.  TRY
  930.   Writer := TWriter.Create(Stream,1024);
  931.   WITH Writer DO
  932.    TRY
  933.     WriteString(FileSignature);
  934.     WriteInteger(FileVersion);
  935.     WriteBoolean(ShowAllFieldsMenuItem.Checked);
  936.     {* Table Tab *}
  937.     WITH AliasComboBox DO WriteString(Items[ItemIndex]);
  938.     WITH TableComboBox DO WriteString(Items[ItemIndex]);
  939.     WITH IndexComboBox DO WriteString(Items[ItemIndex]);
  940.     FLinkList.Write(Writer);
  941.     WriteInteger(SelectFldListBox.Items.Count);
  942.     FOR i := 0 TO SelectFldListBox.Items.Count - 1 DO
  943.      WriteString(SelectFldListBox.Items[i]);
  944.  
  945.     {* Build Tab *}
  946.     WriteString(BuildTimeLabel.Caption);
  947.     WriteString(WordCountLabel.Caption);
  948.     WriteString(MemUsedLabel.Caption);
  949.     WriteString(MaxMemLabel.Caption);
  950.     WriteString(DBSizeLabel.Caption);
  951.     WriteString(MBSizeLabel.Caption);
  952.     WriteString(CompressionLabel.Caption);
  953.  
  954.     WriteString(WordsEdit.Text);
  955.     WriteString(KeyViolEdit.Text);
  956.     WriteBoolean(FileCompressionCheckBox.Checked);
  957.  
  958.     WriteString(DelimsEdit.Text);
  959.  
  960.     WriteInteger(IndexModeComboBox.ItemIndex);
  961.     WriteBoolean(StrictCheckingCheckBox.Checked);
  962.  
  963.     WriteString(MinWordLenEdit.Text);
  964.     WriteString(RecordLimitEdit.Text);
  965.     WriteInteger(MemoryComboBox.ItemIndex);
  966.     WriteBoolean(AltMemMgrCheckBox.Checked);
  967.  
  968.     {* Search Tab *}
  969.     WriteString(SearchComboBox.Text);
  970.  
  971.     WriteString(WordsBtn.Caption);
  972.     WriteString(RecordsBtn.Caption);
  973.     WriteString(ElapsedTimeLabel.Caption);
  974.  
  975.     WriteInteger(SearchLogicRadioGroup.ItemIndex);
  976.     WriteInteger(SearchModeRadioGroup.ItemIndex);
  977.     WriteInteger(RankModeRadioGroup.ItemIndex);
  978.     { SubFields not saved }
  979.  
  980.     WriteString(CacheMemoryLimitEdit.Text);
  981.  
  982.     WriteInteger(MatchingWordsListBox.Items.Count);
  983.     FOR i := 0 TO MatchingWordsListBox.Items.Count - 1 DO
  984.      WriteString(MatchingWordsListBox.Items[i]);
  985.  
  986.     WriteString(MatchedEdit.Text);
  987.     WriteString(MatchRecordLimitEdit.Text);
  988.     WriteString(AnyCharEdit.Text);
  989.     WriteString(OneCharEdit.Text);
  990.     WriteString(NearWordEdit.Text);
  991.  
  992.     {* Reserved for future use *}
  993.     FOR i := 0 TO 3 DO WriteString('~~~');
  994.    FINALLY
  995.     Free
  996.    END
  997.  FINALLY
  998.   Stream.Free
  999.  END
  1000. end;
  1001.  
  1002. procedure TMainForm.OpenMenuItemClick(Sender: TObject);
  1003. VAR      Stream    : TFileStream;
  1004.       Reader    : TReader;
  1005.       Count,i,j : INTEGER;
  1006.       List        : TStrings;
  1007.       Version   : LONGINT;
  1008.       Open        : BOOLEAN;
  1009. begin
  1010.  List := TStringList.Create;
  1011.  WITH OpenDialog1 DO
  1012.   TRY
  1013.    Session.GetAliasParams(AliasComboBox.Text,List);
  1014.    InitialDir := List.Values['PATH'];
  1015.    Open := Execute;
  1016.    IF Open THEN FFileName := FileName
  1017.   FINALLY
  1018.    List.Free
  1019.   END;
  1020.  IF NOT Open THEN EXIT;
  1021.  Stream := TFileStream.Create(FFileName,fmOpenRead);
  1022.  TRY
  1023.   Reader := TReader.Create(Stream,1024);
  1024.   WITH Reader DO
  1025.    TRY
  1026.     IF ReadString <> FileSignature THEN
  1027.      RAISE EDictionary.Create('Invalid file format!');
  1028.     Version := ReadInteger;
  1029.     ShowAllFieldsMenuItem.Checked := NOT ReadBoolean;
  1030.     ShowAllFieldsMenuItemClick(ShowAllFieldsMenuItem);
  1031.     {* Table Tab *}
  1032.     SetComboBoxIndex(AliasComboBox,ReadString);
  1033.     AliasComboBoxChange(NIL);
  1034.     SetComboboxIndex(TableComboBox,ReadString);
  1035.     TableComboBoxChange(NIL);
  1036.     SetComboBoxIndex(IndexComboBox,ReadString);
  1037.     IndexComboboxChange(NIL);
  1038.  
  1039.     FLinkList.Read(Reader);
  1040.     FOR i := 0 TO FLinkList.Count - 1 DO
  1041.      WITH TLinkData(FLinkList.Items[i]) DO
  1042.       BEGIN
  1043.        List := TStringList.Create;
  1044.        TRY
  1045.     DisplayFieldsList(List);
  1046.     FOR j := 0 TO List.Count - 1 DO
  1047.      AvailFldListBox.Items.Add(JustFileName(LinkTableName) + List[j])
  1048.        FINALLY
  1049.     List.Free
  1050.        END;
  1051.        CreateLinkFields(SearchTable1)
  1052.       END;
  1053.  
  1054.     Count := ReadInteger;
  1055.     FOR i := 1 TO Count DO
  1056.      BEGIN
  1057.       j := AvailFldListBox.Items.IndexOf(ReadString);
  1058.       IF j >= 0 THEN AvailFldListBox.Selected[j] := TRUE
  1059.      END;
  1060.     MoveRightBtnClick(NIL);
  1061.  
  1062.     {* Build Tab *}
  1063.     BuildTimeLabel.Caption := ReadString;
  1064.     WordCountLabel.Caption := ReadString;
  1065.     MemUsedLabel.Caption   := ReadString;
  1066.     MaxMemLabel.Caption    := ReadString;
  1067.     DBSizeLabel.Caption    := ReadString;
  1068.     MBSizeLabel.Caption    := ReadString;
  1069.     CompressionLabel.Caption := ReadString;
  1070.  
  1071.     WordsEdit.Text   := ReadString;
  1072.     KeyViolEdit.Text := ReadString;
  1073.     FileCompressionCheckBox.Checked := ReadBoolean;
  1074.  
  1075.     DelimsEdit.Text := ReadString;
  1076.  
  1077.     IndexModeComboBox.ItemIndex    := ReadInteger;
  1078.     StrictCheckingCheckBox.Checked := ReadBoolean;
  1079.  
  1080.     MinWordLenEdit.Text       := ReadString;
  1081.     RecordLimitEdit.Text      := ReadString;
  1082.     MemoryComboBox.ItemIndex  := ReadInteger;
  1083.     AltMemMgrCheckBox.Checked := ReadBoolean;
  1084.  
  1085.     {* Search Tab *}
  1086.     SearchComboBox.Text := ReadString;
  1087.  
  1088.     WordsBtn.Caption         := ReadString;
  1089.     RecordsBtn.Caption         := ReadString;
  1090.     ElapsedTimeLabel.Caption := ReadString;
  1091.  
  1092.     SearchLogicRadioGroup.ItemIndex := ReadInteger;
  1093.     SearchModeRadioGroup.ItemIndex  := ReadInteger;
  1094.     RankModeRadioGroup.ItemIndex    := ReadInteger;
  1095.  
  1096.     CacheMemoryLimitEdit.Text := ReadString;
  1097.  
  1098.     MatchingWordsListBox.Items.Clear;
  1099.     Count := ReadInteger;
  1100.     FOR i := 0 TO Count - 1 DO
  1101.      MatchingWordsListBox.Items.Add(ReadString);
  1102.  
  1103.     MatchedEdit.Text          := ReadString;
  1104.     MatchRecordLimitEdit.Text := ReadString;
  1105.     AnyCharEdit.Text          := ReadString;
  1106.     OneCharEdit.Text          := ReadString;
  1107.     NearWordEdit.Text          := ReadString;
  1108.     {* Reserved for future use *}
  1109.     FOR i := 0 TO 3 DO ReadString;
  1110.    FINALLY
  1111.     Free
  1112.    END
  1113.  FINALLY
  1114.   Stream.Free
  1115.  END;
  1116. {$IFDEF Debug}
  1117.  SearchTable1.Open;
  1118.  MatchTable1.DatabaseName := SearchTable1.DatabaseName;
  1119.  MatchTable1.TableName := MatchedEdit.Text;
  1120.  KeyViolTable1.TableName := AliasToPath(KeyViolEdit.Text);
  1121.  WordsTable1.DatabaseName := SearchTable1.DatabaseName;
  1122.  WordsTable1.TableName := WordsEdit.Text;
  1123.  WordsTable1.IndexFieldNames := 'Word';
  1124.  WordsTable1.Exclusive := TRUE;
  1125.  WordsTable1.Open;
  1126.  Pages := Pages + [pgSearch]
  1127.  {$ENDIF}
  1128. end;
  1129.  
  1130. procedure TMainForm.FormDestroy(Sender: TObject);
  1131. begin
  1132.  FLinkList.Free
  1133. end;
  1134.  
  1135. procedure TMainForm.WordsTable1AfterOpen(DataSet: TDataset);
  1136. begin
  1137.  DataSet.Tag := GetRecordSize(DataSet);
  1138.  WordsTableMenuItem.Enabled := TRUE
  1139. end;
  1140.  
  1141. procedure TMainForm.AnyCharEditExit(Sender: TObject);
  1142. begin
  1143.  WITH SearchBtn DO
  1144.   BEGIN
  1145.    Enabled := LENGTH((Sender AS TEdit).Text) = 1;
  1146.    IF NOT Enabled THEN
  1147.     BEGIN
  1148.      MessageDlg('Cannot search without valid wildcards',mtError,[mbOk],0);
  1149.      (Sender AS TEdit).SetFocus
  1150.     END
  1151.   END
  1152. end;
  1153.  
  1154. procedure TMainForm.IntegerEditExit(Sender: TObject);
  1155.  
  1156.  PROCEDURE Error;
  1157.  BEGIN
  1158.   WITH Sender AS TEdit DO
  1159.    BEGIN
  1160.     IF Tag = 0 THEN
  1161.      MessageDlg('Value must be a positive integer or blank',mtError,[mbOk],0)
  1162.     ELSE
  1163.      MessageDlg('Value must be in the range ' +
  1164.         IntToStr(LOWORD(Tag)) + ' - ' + IntToStr(HIWORD(Tag)),
  1165.         mtError,[mbOk],0);
  1166.     SetFocus
  1167.    END
  1168.  END;
  1169.  
  1170. begin
  1171.  WITH Sender AS TEdit DO
  1172.   TRY
  1173.    IF Tag = 0 THEN
  1174.     IF (Text <> '') AND (StrToInt(Text) < 0) THEN Error
  1175.     ELSE
  1176.    ELSE
  1177.     IF (StrToInt(Text) > HIWORD(Tag)) OR
  1178.        (StrToInt(Text) < LOWORD(Tag)) THEN Error
  1179.   EXCEPT
  1180.    ON EConvertError DO Error
  1181.   END
  1182. end;
  1183.  
  1184. procedure TMainForm.IndexModeComboBoxChange(Sender: TObject);
  1185. begin
  1186.  WITH Sender AS TComboBox,MakeDictionary1 DO
  1187.   BEGIN
  1188.    DataSource := SearchDataSource;
  1189.    StrictChecking := StrictCheckingCheckBox.Checked;
  1190.    TRY
  1191.     IndexMode := TIndexMode(ItemIndex)
  1192.    EXCEPT
  1193.     ON EDictionary DO
  1194.      ItemIndex := ORD(SafeIndexMode(SearchTable1))
  1195.    END
  1196.   END
  1197. end;
  1198.  
  1199. procedure TMainForm.ShowAllFieldsMenuItemClick(Sender: TObject);
  1200. VAR i : INTEGER;
  1201. begin
  1202.  WITH SearchTable1,Sender AS TMenuItem DO
  1203.   BEGIN
  1204.    Checked := NOT Checked;
  1205.    FOR i := 0 TO FieldCount - 1 DO
  1206.     WITH Fields[i] DO
  1207.      Visible := Checked OR (SelectFldListBox.Items.IndexOf(FieldName) <> -1)
  1208.   END
  1209. end;
  1210.  
  1211. procedure TMainForm.SearchTable1AfterOpen(DataSet: TDataset);
  1212. VAR F : TForm;
  1213. begin
  1214.  SearchTableMenuItem.Enabled := TRUE;
  1215.  F := FindForm('Search Table');
  1216.  IF F <> NIL THEN F.Caption := UpperCase(TTable(DataSet).TableName)
  1217. end;
  1218.  
  1219. procedure TMainForm.SearchTable1BeforeClose(DataSet: TDataset);
  1220. VAR      F : TForm;
  1221. begin
  1222.  SearchTableMenuItem.Enabled := FALSE;
  1223.  F := FindForm(UpperCase(TTable(DataSet).TableName));
  1224.  IF F <> NIL THEN F.Caption := 'Search Table'
  1225. end;
  1226.  
  1227. procedure TMainForm.WordsTable1BeforeClose(DataSet: TDataset);
  1228. begin
  1229.  WordsTableMenuItem.Enabled := FALSE;
  1230. end;
  1231.  
  1232. procedure TMainForm.MatchTable1AfterOpen(DataSet: TDataset);
  1233. begin
  1234.  MatchTableMenuItem.Enabled := TRUE;
  1235.  RecordsBtn.Enabled := TRUE
  1236. end;
  1237.  
  1238. procedure TMainForm.MatchTable1BeforeClose(DataSet: TDataset);
  1239. begin
  1240.  MatchTableMenuItem.Enabled := FALSE;
  1241.  RecordsBtn.Enabled := FALSE
  1242. end;
  1243.  
  1244. procedure TMainForm.SaveAsMenuItemClick(Sender: TObject);
  1245. begin
  1246.  FFilename := 'LINK1.RDM';
  1247.  SaveMenuItemClick(Sender)
  1248. end;
  1249.  
  1250. procedure TMainForm.ExitMenuItemClick(Sender: TObject);
  1251. begin
  1252.  Application.Terminate
  1253. end;
  1254.  
  1255. procedure TMainForm.About1Click(Sender: TObject);
  1256. var F : TForm;
  1257. begin
  1258.  Application.CreateForm(TAboutForm,F);
  1259.  F.ShowModal
  1260. end;
  1261.  
  1262. procedure TMainForm.TabbedNotebook1Change(Sender: TObject; NewTab: Integer;
  1263.   var AllowChange: Boolean);
  1264. begin
  1265.  AllowChange := TPage(NewTab) IN Pages;
  1266. end;
  1267.  
  1268. procedure TMainForm.WordsEditExit(Sender: TObject);
  1269. begin
  1270.  WITH WordsTable1 DO
  1271.   IF Active AND (CompareText(WordsEdit.Text,TableName) <> 0) THEN
  1272.    BEGIN
  1273.     Close;
  1274.     DeleteTable;
  1275.     Pages := Pages - [pgSearch]
  1276.    END
  1277. end;
  1278.  
  1279. procedure TMainForm.MatchedEditExit(Sender: TObject);
  1280. begin
  1281.  WITH MatchTable1 DO
  1282.   IF Active AND (CompareText(WordsEdit.Text,TableName) <> 0) THEN
  1283.    BEGIN
  1284.     Close;
  1285.     DeleteTable
  1286.    END
  1287. end;
  1288.  
  1289. procedure TMainForm.NewMenuItemClick(Sender: TObject);
  1290. begin
  1291.  INC(FFileNo);
  1292.  SetDefaults1;
  1293.  SetDefaults2;
  1294.  TabbedNotebook1.PageIndex := 0;
  1295. end;
  1296.  
  1297. procedure TMainForm.KeyViolTable1AfterOpen(DataSet: TDataset);
  1298. begin
  1299.  KeyViolTableMenuItem.Enabled := TRUE
  1300. end;
  1301.  
  1302. procedure TMainForm.KeyViolTable1BeforeClose(DataSet: TDataset);
  1303. begin
  1304.  KeyViolTableMenuItem.Enabled := FALSE
  1305. end;
  1306.  
  1307. procedure TMainForm.KeyViolTableMenuItemClick(Sender: TObject);
  1308. begin
  1309.  ViewGridForm(KeyViolDataSource)
  1310. end;
  1311.  
  1312. procedure TMainForm.KeyViolEditExit(Sender: TObject);
  1313. begin
  1314.  WITH KeyViolTable1 DO
  1315.   IF Active AND (CompareText(KeyViolEdit.Text,TableName) <> 0) THEN
  1316.    BEGIN
  1317.     Close;
  1318.     DeleteTable
  1319.    END
  1320. end;
  1321.  
  1322. procedure TMainForm.ShowHintsMenuItemClick(Sender: TObject);
  1323. begin
  1324.  WITH ShowHintsMenuItem DO
  1325.   BEGIN
  1326.    Checked := NOT Checked;
  1327.    Application.ShowHint := Checked
  1328.   END
  1329. end;
  1330.  
  1331. PROCEDURE TMainForm.UpdateCacheStats;
  1332. BEGIN
  1333.  WITH SearchDictionary1 DO
  1334.   BEGIN
  1335.    DiskReadsLabel.Caption   := Format('%8.0n',[DiskReads + 0.001]);
  1336.    CacheReadsLabel.Caption  := Format('%8.0n',[CacheReads + 0.001]);
  1337.    SourceReadsLabel.Caption := Format('%8.0n',[SourceReads + 0.001]);
  1338.    MemoryUsageLabel.Caption := Format('%8.0n',[MemoryUsage + 0.001])
  1339.   END
  1340. END;
  1341.  
  1342. procedure TMainForm.SearchDictionary1Search(Sender: TObject);
  1343. begin
  1344.  UpdateElapsedTime(ElapsedTimeLabel);
  1345.  IF (SearchOptionsRadioGroup.ItemIndex = 3) OR
  1346.     (dsDone IN SearchDictionary1.State) THEN UpdateCacheStats;
  1347.  Application.ProcessMessages;
  1348.  IF NOT FContinue THEN
  1349.   WITH SearchDictionary1 DO
  1350.    State := State + [dsAbort]
  1351. end;
  1352.  
  1353. procedure TMainForm.Contents1Click(Sender: TObject);
  1354. begin
  1355.  Application.HelpCommand(HELP_CONTENTS,0)
  1356. end;
  1357.  
  1358. procedure TMainForm.WordsBtnClick(Sender: TObject);
  1359. begin
  1360.  SearchOptionsRadioGroup.ItemIndex := 5
  1361. end;
  1362.  
  1363. procedure TMainForm.RecordsBtnClick(Sender: TObject);
  1364. begin
  1365.  MatchTableMenuItemClick(Sender)
  1366. end;
  1367.  
  1368. procedure TMainForm.SearchComboBoxChange(Sender: TObject);
  1369. begin
  1370.  WITH Sender AS TComboBox DO
  1371.   BEGIN
  1372.    SearchBtn.Enabled := Text <> '';
  1373.    SearchBtn.Default := SearchBtn.Enabled;
  1374.  { SearchPrevBtn.Default := NOT SearchBtn.Enabled }
  1375.   END
  1376. end;
  1377.  
  1378. procedure TMainForm.SearchOptionsRadioGroupClick(Sender: TObject);
  1379. begin
  1380.  WITH Sender AS TRadioGroup DO
  1381.   SearchNotebook.PageIndex := ItemIndex
  1382. end;
  1383.  
  1384. procedure TMainForm.BuildOptionsRadioGroupClick(Sender: TObject);
  1385. begin
  1386.  WITH Sender AS TRadioGroup DO
  1387.   BEGIN
  1388.    BuildNotebook.PageIndex := ItemIndex;
  1389.  { CASE ItemIndex OF
  1390.     0 : WordsEdit.SetFocus;
  1391.     1 : DelimsEdit.SetFocus;
  1392.     2 : IndexModeComboBox.SetFocus;
  1393.     3 : MinWordLenEdit.SetFocus
  1394.    END }
  1395.   END
  1396. end;
  1397.  
  1398. procedure TMainForm.SubFieldsAddAllBtnClick(Sender: TObject);
  1399. begin
  1400.  WITH SubFieldListBox.Items DO
  1401.   BEGIN
  1402.    Clear;
  1403.    Assign(SelectFldListBox.Items)
  1404.   END
  1405. end;
  1406.  
  1407. procedure TMainForm.SubFieldsRemoveBtnClick(Sender: TObject);
  1408. begin
  1409.  WITH SubFieldListBox DO
  1410.   IF ItemIndex <> -1 THEN Items.Delete(ItemIndex)
  1411. end;
  1412.  
  1413. PROCEDURE TMainForm.SetPages(Value : TPages);
  1414. BEGIN
  1415.  IF Value <> FPages THEN
  1416.   BEGIN
  1417.    FPages := Value;
  1418.    CASE TPage(TabbedNotebook1.PageIndex) OF
  1419.     pgTable : NextBtn.Enabled := pgTable IN Pages;
  1420.     pgBuild : NextBtn.Enabled := pgBuild IN Pages
  1421.    END
  1422.   END
  1423. END;
  1424.  
  1425. procedure TMainForm.SubFieldListBoxDblClick(Sender: TObject);
  1426. begin
  1427.  WITH Sender AS TListBox,Items DO
  1428.   IF Count > 1 THEN Delete(ItemIndex)
  1429. end;
  1430.  
  1431. procedure TMainForm.ResetBtnClick(Sender: TObject);
  1432. begin
  1433.  SearchDictionary1.ResetStats;
  1434.  UpdateCacheStats
  1435. end;
  1436.  
  1437. procedure TMainForm.FlushBtnClick(Sender: TObject);
  1438. begin
  1439.  SearchDictionary1.FlushCache;
  1440.  UpdateCacheStats
  1441. end;
  1442.  
  1443. procedure TMainForm.TabbedNotebook1Click(Sender: TObject);
  1444. begin
  1445.  CASE TPage(TabbedNotebook1.PageIndex) OF
  1446.   pgIntroduction : BEGIN
  1447.             PrevBtn.Enabled := FALSE;
  1448.             NextBtn.Enabled := TRUE;
  1449.             BuildBtn.Visible := FALSE;
  1450.             ActiveControl := NextBtn;
  1451.            END;
  1452.   pgTable     : BEGIN
  1453.             SearchDictionary1.FlushCache;
  1454.             PrevBtn.Enabled := TRUE;
  1455.             NextBtn.Enabled := pgBuild IN Pages;
  1456.             BuildBtn.Visible := FALSE;
  1457.             ActiveControl := AliasComboBox;
  1458.            END;
  1459.   pgBuild     : BEGIN
  1460.             SearchDictionary1.FlushCache;
  1461.             PrevBtn.Enabled := TRUE;
  1462.             NextBtn.Enabled := pgSearch IN Pages;
  1463.             BuildBtn.Visible := TRUE;
  1464.             ActiveControl := BuildBtn;
  1465.            END;
  1466.   pgSearch     : BEGIN
  1467.             SearchDictionary1.FlushCache;
  1468.             PrevBtn.Enabled := TRUE;
  1469.             NextBtn.Enabled := FALSE;
  1470.             BuildBtn.Visible := FALSE;
  1471.             ActiveControl := SearchComboBox;
  1472.             SubFieldsAddAllBtnClick(NIL);
  1473.            END;
  1474.   END
  1475.  
  1476. end;
  1477.  
  1478. procedure TMainForm.SearchModeRadioGroupClick(Sender: TObject);
  1479. begin
  1480.  WITH Sender AS TRadioGroup DO
  1481.   SearchDictionary1.SearchMode := TSearchMode(ItemIndex);
  1482.  SearchBtn.Caption := SearchBtnCaption[SearchDictionary1.SearchMode];
  1483.  SearchBtn.Hint := SearchBtnHint[SearchDictionary1.SearchMode]
  1484. end;
  1485.  
  1486. procedure TMainForm.MakeDictionary1PhaseOne(Sender: TObject);
  1487. VAR      CurrentTics : LONGINT;
  1488.       {$IFDEF Debug}
  1489.       CS : TCacheStats;
  1490.        {$IFDEF WIN32}
  1491.       MS : TMemoryStatus;
  1492.        {$ENDIF}
  1493.       {$ENDIF}
  1494. BEGIN
  1495.  CurrentTics := GetTickCount;
  1496.  WITH TMakeDictionary(Sender), PhaseForm DO
  1497.   BEGIN
  1498.    IF State = [dsPhaseOne,dsStart] THEN
  1499.     BEGIN
  1500.      Gauge.MinValue := 0;
  1501.      IF RecordLimit = 0 THEN
  1502.       Gauge.MaxValue := SearchTable1.RecordCount
  1503.      ELSE
  1504.       Gauge.MaxValue := MinLong(RecordLimit,SearchTable1.RecordCount);
  1505.      Gauge.Progress := 0;
  1506.      FLastUpd := CurrentTics;
  1507.      Caption := 'Phase One';
  1508.      CanExpand := FALSE;
  1509.      Show;
  1510.      SetFocus;
  1511.      DBSizeLabel.Caption := '';
  1512.      MBSizeLabel.Caption := '';
  1513.      CompressionLabel.Caption := '';
  1514.     END;
  1515.    IF (CurrentTics - FLastUpd > RefreshTics) OR (dsDone IN State) THEN
  1516.     BEGIN
  1517.      FLastUpd := CurrentTics;
  1518.      Gauge.Progress := RecordNo;
  1519.      Self.BuildTimeLabel.Caption := FormatDateTime('  hh:nn:ss',Now - StartTime);
  1520.      Self.MemUsedLabel.Caption     := Format('%10.0n',[MemoryUsage + 0.001]);
  1521.      Self.MaxMemLabel.Caption     := Format('%10.0n',[MaxMemUsed + 0.001]);
  1522.      Self.WordCountLabel.Caption := Format('%10.0n',[CacheCount - OmitList.Count + 0.001]);
  1523.      Application.ProcessMessages;
  1524.      IF NOT PhaseForm.Visible THEN State := State + [dsAbort]
  1525.     END;
  1526.    {$IFDEF Debug}
  1527.    IF dsCompress IN State THEN
  1528.     BEGIN
  1529.      {$IFDEF WIN32}
  1530.      MS.dwLength := SIZEOF(MS);
  1531.      GlobalMemoryStatus(MS);
  1532.      DBSizelabel.Caption := IntToStr(MS.dwTotalVirtual - MS.dwAvailVirtual);
  1533.      {$ENDIF}
  1534.      GetCacheStats(CS);
  1535.      WITH CS,MBSizeLabel DO
  1536.       BEGIN
  1537.        IF dsStart IN State THEN Font.Color := clRed
  1538.        ELSE Font.Color := clBlack;
  1539.        Caption := IntToStr(Compressed) + ':' + IntToStr(Uncompressed)
  1540.       END;
  1541.      WITH CS,CompressionLabel DO
  1542.       BEGIN
  1543.        IF dsStart IN State THEN Font.Color := clRed
  1544.        ELSE Font.Color := clBlack;
  1545.        Caption := IntToStr(LRU) + ':' + IntToStr(CompressLRU)
  1546.       END;
  1547.      Application.ProcessMessages;
  1548.      IF NOT PhaseForm.Visible THEN State := State + [dsAbort]
  1549.     END
  1550.    {$ENDIF}
  1551.   END
  1552. end;
  1553.  
  1554. procedure TMainForm.MakeDictionary1PhaseTwo(Sender: TObject);
  1555. VAR      CurrentTics : LONGINT;
  1556. BEGIN
  1557.  CurrentTics := GetTickCount;
  1558.  WITH TMakeDictionary(Sender), PhaseForm DO
  1559.   BEGIN
  1560.    IF dsStart IN State THEN
  1561.     BEGIN
  1562.      Caption := 'Phase Two';
  1563.      Gauge.MinValue := 0;
  1564.      Gauge.MaxValue := CacheCount - OmitList.Count;
  1565.      Gauge.Progress := 0;
  1566.      FLastUpd := CurrentTics;
  1567.      IF NOT FileCompression THEN CompressionLabel.Caption := '       N/A'
  1568.     END;
  1569.    IF (CurrentTics - FLastUpd > RefreshTics) OR (dsDone IN State) OR (DiskInserts = Gauge.MaxValue) THEN
  1570.     BEGIN
  1571.      FLastUpd := CurrentTics;
  1572.      Gauge.Progress := DiskInserts;
  1573.      Self.BuildTimeLabel.Caption := FormatDateTime('  hh:nn:ss',Now - StartTime);
  1574.      Self.MemUsedLabel.Caption     := Format('%10.0n',[MemoryUsage + 0.001]);
  1575.      Self.MaxMemLabel.Caption     := Format('%10.0n',[MaxMemUsed + 0.001]);
  1576.      Self.DBSizeLabel.Caption     := Format('%10.0n',[DiskInserts * WordsTable1.Tag + 0.001]);
  1577.      Self.MBSizeLabel.Caption     := Format('%10.0n',[BlobBytesWritten + 0.001]);
  1578.      IF (DiskInserts > 0) AND FileCompression THEN
  1579.       Self.CompressionLabel.Caption :=
  1580.        Format('%9.1n%%',[(1.0 - BlobBytesWritten / (DiskInserts * ((IndexRange + 8) SHR 3))) * 100]);
  1581.      Application.ProcessMessages;
  1582.      IF NOT PhaseForm.Visible THEN State := State + [dsAbort]
  1583.     END
  1584.   END
  1585. end;
  1586.  
  1587. end.
  1588.